import {
  AfterViewInit,
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  Input,
  NgZone,
  OnDestroy,
  OnInit,
  Pipe,
  PipeTransform,
  ViewChild,
  ViewEncapsulation,
} from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { DomSanitizer, SafeHtml, SafeResourceUrl, SafeScript, SafeStyle, SafeUrl } from '@angular/platform-browser';
import { filter } from 'rxjs/operators';
import { some as _some } from 'lodash';
import { InputBoolean } from '@iux/live';
import {
  CaseConfigType,
  Common,
  DESCRIPTION_MODULE,
  FAQ_DOC_MODULE,
  Features,
  getLocalStorage,
  I18NService,
  LOCAL_STORAGE_KEY,
  NO_DESIGN_DOC_MODULE,
  USER_TYPE,
} from '@shared';
import { APIHost, AppContentRouter } from 'cxd/business/app-content/app-content.router';
import { environment } from '../../../../environments/environment';

@Pipe({
  name: 'safe',
})
export class SafePipe implements PipeTransform {
  constructor(protected dom: DomSanitizer) {}
  public transform(value, type): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {
    switch (type) {
      case 'html':
        return this.dom.bypassSecurityTrustHtml(value);
      case 'style':
        return this.dom.bypassSecurityTrustStyle(value);
      case 'script':
        return this.dom.bypassSecurityTrustScript(value);
      case 'url':
        return this.dom.bypassSecurityTrustUrl(value);
      case 'resourceUrl':
        return this.dom.bypassSecurityTrustResourceUrl(value);
      default:
        return value;
    }
  }
}

@Component({
  selector: 'app-case-content',
  templateUrl: './case-content.component.html',
  styleUrls: ['./case-content.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  host: {
    class: 'case-content',
  },
})
export class CaseContentComponent implements OnInit, AfterViewInit, OnDestroy {
  @Input() urlGroup;
  @Input() active = 'demo';
  @Input() @InputBoolean() showTabs = true;

  @ViewChild('demoContent') demoContent;
  @ViewChild('apiContent') apiContent;
  @ViewChild('designContent') designContent;

  routers = [];
  urls = [];
  basePath = APIHost;
  routerEvents$;
  activeRouterData$;

  lang;
  title;
  tabsData = [];

  features;

  currentCom: CaseConfigType;
  codeType = [];

  faqUrl = '';
  faq;

  design;
  designUrl;
  designName = [];

  scrollHeight = 0;

  constructor(
    public i18n: I18NService,
    private router: Router,
    private activeRouter: ActivatedRoute,
    private zone: NgZone,
    private cdr: ChangeDetectorRef
  ) {}

  ngOnInit(): void {
    this.lang = this.i18n.language;
    this.codeType = ['html', 'ts', 'module'];
    this.initTitle();
    this.initTabs();
    this.initMarkdownContent();
    this.initFeatures();

    this.routerEvents$ = this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => {
      this.initTitle();
      this.initMarkdownContent();
    });

    this.activeRouterData$ = this.activeRouter.data.subscribe(res => {
      this.setCaseData(res);
    });
  }

  ngAfterViewInit(): void {
    this.scrollEvent();

    setTimeout(() => {
      document.querySelector('.live-design-content-wrapper').addEventListener('scroll', () => this.scrollEvent(), false);
      this.zone.runOutsideAngular(() => {
        document.querySelector('.live-design-content-wrapper').scrollTop = 0;
      });
    }, 100);
  }

  ngOnDestroy(): void {
    this.routerEvents$.unsubscribe();
    this.activeRouterData$.unsubscribe();
  }

  initTitle(): void {
    // TODO: 重构国际化，key统一，减少逻辑代码适配
    this.routers = AppContentRouter.slice(0);
    this.urls = this.router.url.split('/');
    const urlValue = this.urls[this.urls.length - 1];
    const { type, path } = this.routers.find(router => router.path === urlValue);
    let value = path;

    // 适配原有国际化，当前版本不做调整
    if (DESCRIPTION_MODULE.indexOf(type) > -1) {
      value = `${type}-${path}`;
    }

    this.title = type === 'join-us' ? this.i18n.get('join-web-developer') : `${this.i18n.get(value)[0]} ${this.i18n.get(value)[1]}`;
  }

  initFeatures(): void {
    this.features = Features.find(({ path }) => location.pathname.endsWith(path));
  }

  initTabs(): void {
    const design = {
      key: 'design',
      title: this.i18n.get('case-content-tabs-design'),
      content: this.designContent,
      hidden: NO_DESIGN_DOC_MODULE.includes(this.urls[this.urls.length - 1]),
    };
    const api = { key: 'api', title: this.i18n.get('case-content-tabs-api'), content: this.apiContent, hidden: false };
    const demo = { key: 'demo', title: this.i18n.get('case-content-tabs-demo'), content: this.demoContent, hidden: false };
    const userType = getLocalStorage(LOCAL_STORAGE_KEY.LIVE_USER_TYPE) || USER_TYPE.DEVELOPER;

    this.tabsData = userType === USER_TYPE.DEVELOPER ? [demo, api] : [demo, api];
  }

  initMarkdownContent(): void {
    const name = this.router.url.replace(`/${this.urlGroup}/`, '').replace('/', '-');
    const prefix = environment.baseUrl;

    // 适配不同分组的markdownUrl
    const urlConfig = {
      foundation: `assets/${this.urlGroup}/${name}/index.md`,
      develop: `assets/${this.urlGroup}/${name}.md`,
      components: `showcase/${name}/index.md`,
      pattern: `assets/${this.urlGroup}/${name}/index.md`,
      'join-us': `assets/${this.urlGroup}/index.md`,
    };

    // 处理无设计md文档场景
    if (!NO_DESIGN_DOC_MODULE.includes(name)) {
      this.designUrl = `/${prefix}${urlConfig[this.urlGroup]}`;
    }

    // 处理有faq md文档场景
    if (FAQ_DOC_MODULE.includes(name)) {
      this.faqUrl = `/${prefix}showcase/${name}/faq.md`;
    }
  }

  getApiDataConfig(api): Array<{ [key: string]: any }> {
    if (api.isAttr) {
      return [
        {
          label: this.i18n.get('Case_AttrName'),
          width: '230px',
        },
        {
          label: this.i18n.get('Case_Description'),
          width: '45%',
        },
        {
          label: this.i18n.get('Case_Type'),
          width: 'auto',
        },
        {
          label: this.i18n.get('Case_Default'),
          width: 'auto',
        },
        {
          label: this.i18n.get('Case_Global'),
          width: '80px',
          hidden: !api.hasGlobal,
        },
      ];
    } else {
      return [
        {
          label: this.i18n.get('Case_EventName'),
          width: 'auto',
        },
        {
          label: this.i18n.get('Case_Param'),
          width: 'auto',
        },
        {
          label: this.i18n.get('Case_Description'),
          width: '45%',
        },
      ];
    }
  }

  setCaseData(data): void {
    if (!data.__zone_symbol__value) {
      return;
    }

    this.currentCom = data.__zone_symbol__value;
    const { component, mApi, selector, api, event } = this.currentCom;

    component.forEach(com => {
      com['demoHidden'] = com.devDebug && window.location.hostname === Common.PRODUCT_HOST_NAME;
    });

    if (!mApi) {
      this.currentCom.mApi = [{ name: selector, name_en: selector, api, event }];
    }

    this.currentCom.mApi.forEach(item => {
      item.hasGlobal = _some(item.api, global => !!global.global);

      // 默认显示内容
      item.isAttr = !!item.api?.length;
    });
  }

  attrEventChange(value, data): void {
    data.isAttr = value === 'attr';
  }

  beforeTabChange = (originTab): void => {
    originTab.scrollY = document.querySelector('.live-design-content-wrapper').scrollTop;
  };

  afterTabChange = (_, activeTab): void => {
    setTimeout(() => {
      document.querySelector('.live-design-content-wrapper').scrollTop = activeTab.scrollY || 0;
      this.scrollEvent();
    }, 0);
  };

  scrollEvent(): void {
    const { scrollTop } = document.querySelector('.live-design-content-wrapper');
    const header = document.querySelector('.case-content .case-content-top') as HTMLElement;
    const searchHeader = document.querySelector('.live-design-content-header') as HTMLElement;

    if (scrollTop > 50) {
      header.classList.add('case-content-top-fix');
      searchHeader.classList.add('live-design-content-header-hidden');
    } else {
      header.classList.remove('case-content-top-fix');
      searchHeader.classList.remove('live-design-content-header-hidden');
    }

    if (this.scrollHeight - scrollTop > 0 && scrollTop > 50) {
      header.classList.remove('case-content-top-fix-show');
      searchHeader.classList.remove('live-design-content-header-hidden');
    } else {
      header.classList.add('case-content-top-fix-show');
    }

    this.scrollHeight = scrollTop;
  }

  onError(e): void {
    console.warn(e);
  }

  onLoad(e): void {
    this.faq = e;
  }

  onDesignLoad(e): void {
    this.design = e;

    setTimeout(() => {
      const nameDome = document.querySelectorAll('.design-markdown-container h2');
      nameDome.forEach(item => {
        this.designName.push(item.getAttribute('id'));
      });
      this.cdr.markForCheck();
    }, 100);
  }

  encodeSelector(name: string): string {
    const symbol = ['/'];
    let result = name;
    symbol.forEach(item => {
      result = name?.replace(item, `\\${item}`);
    });
    return result;
  }
}
